package com.kosam.commons.base.util;

import com.kosam.commons.base.exception.InternalServerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Map;

/**
 * Created by tgx on 2017/2/20.
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils{

    private StringUtils() {

    }

    public static class Encode {

        private static Logger log = LoggerFactory.getLogger(Encode.class);
        public static final String ALGORITHM_MD5 = "MD5";
        public static final String ALGORITHM_SHA1 = "SHA1";

        private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

        /**
         * encode string
         *
         * @param algorithm
         * @param content
         * @return String
         */
        public static String encode(String algorithm, String content) {
            if (content == null) {
                return null;
            }

            try {
                MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
                messageDigest.update(content.getBytes());
                return getFormattedText(messageDigest.digest());
            } catch (NoSuchAlgorithmException e) {
                log.error(e.getMessage(), e);
                throw new InternalServerException("No Such Algorithm Exception.");
            }
        }

        public static String md5(String str) {
            return encode(ALGORITHM_MD5, str);
        }

        public static String sha1(String str) {
            return encode(ALGORITHM_SHA1, str);
        }


        /**
         * Takes the raw bytes from the digest and formats them correct.
         *
         * @param bytes the raw bytes from the digest.
         * @return the formatted bytes.
         */
        private static String getFormattedText(byte[] bytes) {
            int len = bytes.length;
            StringBuilder buf = new StringBuilder(len * 2);
            //  convert cipher text to hexadecimal string
            for (int j = 0; j < len; j++) {
                buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
                buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
            }
            return buf.toString();
        }
    }

    public static class Format {

        public static String substitute(String tepl, Map<String, String> params) {
            String text = tepl;
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                if (entry.getValue() != null) {
                    text = text.replaceAll("\\{" + key + "}", safeRegexReplacement(entry.getValue()));
                } else {
                    text = text.replaceAll("\\{" + key + "}", "");
                }
            }
            return text;
        }

        private static String safeRegexReplacement(String replacement) {
            if (replacement == null) {
                return replacement;
            }

            return replacement.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$", "\\\\\\$");
        }
    }

    public static class Random {
        // Maxim: Copied from UUID implementation :)
        private static volatile SecureRandom numberGenerator = null;
        private static final long MSB = 0x8000000000000000L;

        public static String genRandom32Hex() {
            SecureRandom ng = numberGenerator;
            if (ng == null) {
                numberGenerator = ng = new SecureRandom();
            }

            return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
        }

        public static int getPhoneCode(){
            int code = new java.util.Random(System.currentTimeMillis()).nextInt(999999);
            if (code < 100000){
                code = getPhoneCode();
            }
            return code;
        }
    }
}
